package com.cq.hd.order.render.impl;

import com.cq.hd.common.enums.ResponseEnums;
import com.cq.hd.common.enums.biz.ActiveStateEnum;
import com.cq.hd.common.enums.biz.ActiveTypeEnum;
import com.cq.hd.common.response.Throw;
import com.cq.hd.order.api.dto.CreateOrderDto;
import com.cq.hd.order.render.OrderContext;
import com.cq.hd.order.render.OrderRenderStepEnum;
import com.cq.hd.order.render.dto.PriceDetailDto;
import com.cq.hd.order.service.TbOrderService;
import com.cq.hd.product.api.TbActiveApi;
import com.cq.hd.product.api.vo.ActiveVo;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 校验活动信息
 *
 * @author much
 * @since 2024/09/11 23:15
 */
@Component
public class ValidActiveRender extends AbstractRenderStep {

    @Resource
    private TbActiveApi activeApi;
    @Resource
    private TbOrderService orderService;

    @Override
    public OrderRenderStepEnum step() {
        return OrderRenderStepEnum.VALID_ACTIVE;
    }

    @Override
    public void render(OrderContext orderContext) {
        ActiveVo activeVo = activeApi.getById(orderContext.getActiveId()).unpack();
        orderContext.setActiveVo(activeVo);
        // 判断活动类型
        validateActiveType(activeVo);
        // 判断活动状态
        validateActiveState(activeVo);
        // 校验活动库存
        validateActiveStock(orderContext);
        // 限购数量
        validateLimitBuy(orderContext);

        PriceDetailDto priceDetailDTO = orderContext.getPriceDetailDTO();
        priceDetailDTO.setActivePrice(activeVo.getActivePrice());
    }

    // 校验活动类型
    private void validateActiveType(ActiveVo activeVo) {
        List<Integer> supportActiveTypes = Arrays.asList(
                ActiveTypeEnum.GROUP.getValue(), ActiveTypeEnum.ENROLL.getValue(), ActiveTypeEnum.GROUP_ENROLL.getValue());
        Integer activeType = activeVo.getActiveType();
        if (!supportActiveTypes.contains(activeType)) {
            Throw.isBusinessException("该活动不支持下单");
        }
    }

    // 校验活动状态
    private void validateActiveState(ActiveVo activeVo) {
        // 活动被删除 | 未发布
        if (activeVo == null || activeVo.getDelState() != 0 || ActiveStateEnum.NO_RELEASE.getValue().equals(activeVo.getActiveState())) {
            Throw.isBusinessException(ResponseEnums.ACTIVE_DOWN);
        }

        // 活动有效期
        LocalDateTime now = LocalDateTime.now();
        Integer activeState = activeVo.getActiveState();
        LocalDateTime startTime = activeVo.getStartTime();
        LocalDateTime endTime = activeVo.getEndTime();
        if (startTime.isAfter(now)) {
            activeState = ActiveStateEnum.NO_START.getValue();
        } else if (!endTime.isAfter(now)) {
            activeState = ActiveStateEnum.ENDED.getValue();
        } else if (startTime.compareTo(now) <= 0 && endTime.compareTo(now) > 0) {
            activeState = ActiveStateEnum.IN_PROGRESS.getValue();
        }

        if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {
            Throw.isBusinessException("活动已结束");
        }
        if (ActiveStateEnum.NO_START.getValue().equals(activeState)) {
            Throw.isBusinessException("活动未开始");
        }
    }

    // 校验库存
    private void validateActiveStock(OrderContext orderContext) {
        // 判断活动的库存是否充足
        CreateOrderDto createOrderDto = orderContext.getCreateOrderDto();
        Integer remainStock = orderContext.getActiveVo().getRemainStock();
        if (remainStock - createOrderDto.getOrderNum() < 0) {
            Throw.isBusinessException("活动库存不足");
        }
    }

    // 限购
    private void validateLimitBuy(OrderContext orderContext) {
        ActiveVo activeVo = orderContext.getActiveVo();
        CreateOrderDto createOrderDto = orderContext.getCreateOrderDto();
        // 限购数量
        Integer limitBuyNum = activeVo.getLimitBuyNum();
        // 查询下单用户的待支付，待核销、核销中、已核销、已完成的该活动的订单数
        Integer totalOrderCount = orderService.userActiveOrderCount(createOrderDto.getUserId(), activeVo.getId());
        if (limitBuyNum != null && limitBuyNum > 0 && totalOrderCount != null) {
            int canOrderNum = limitBuyNum - totalOrderCount;
            if (createOrderDto.getOrderNum() > canOrderNum) {
                Throw.isBusinessException("已超限购个数");
            }
        }
    }

}
